package com.hyperzsoft.budget;

import java.util.ArrayList;

import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.hyperzsoft.budget.DBProvider.BudgetTable;
import com.hyperzsoft.budget.DBProvider.ExpenseType;
import com.hyperzsoft.utils.ColorSelectBar;

public class EditTypes extends ListActivity {
	static private String TAG = "EditTypes";
	
	private DBProvider mDBProvider;
	private typeListAdapter mAdapter;
	private ArrayList<ExpenseType> mTypes = null;
	private ProgressDialog mProgressDialog = null;
	private Dialog mDialog;
	
	private int mTypeOf;
	private int mSelectedPos = -1;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.types_edit_list_view);
		
		mDBProvider = new DBProvider(this);
		mTypes = new ArrayList<ExpenseType>();
		mAdapter = new typeListAdapter(this, R.layout.types_edit_list_item, mTypes);
		
		if (savedInstanceState != null) {
			mTypeOf = savedInstanceState.getInt("typeOf");
			mSelectedPos = savedInstanceState.getInt("selectedPos");
			mTypes = savedInstanceState.getParcelableArrayList("types");
			
			populateAdapter();
		} else {
			//default to expense types
			mTypeOf = mDBProvider.EXPENSE_TYPES;
			
			//check if there was an extra passed in that will override the default type of
			Bundle bundle = getIntent().getExtras();
			if (bundle != null) {
				if (bundle.containsKey("type_of")) {
					mTypeOf = bundle.getInt("type_of");
				}
			}
			setupListAdapter(false);
		}
		setupListClicks();
	}
	
	private void setupListAdapter(boolean isReload) {
		(new Thread(null, new Runnable() {
			@Override
			public void run() {
				getTypesList();
			}
		}, "BudgetThread")).start();
		
		mProgressDialog = ProgressDialog.show(this,    
				"Please wait...", (isReload) ? "Reloading data ..." : "Retrieving data ...", true);
	}
	
	private void populateAdapter() {
		mAdapter.clear();
		setListAdapter(mAdapter);
		
		for(int i=0;i<mTypes.size();i++)
			mAdapter.add(mTypes.get(i));
		
		mAdapter.notifyDataSetChanged();
	}
	
	private final Runnable returnRes = new Runnable() {
		@Override
		public void run() {
			if(mTypes != null && mTypes.size() > 0){
				populateAdapter();
			}
			
			if (mProgressDialog.isShowing()) mProgressDialog.dismiss();
		}
	};
	
	private void setupListClicks() {
		ListView lv = getListView();
		
		lv.setOnItemLongClickListener(new OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View view,
					int position, long id) {
				
				mSelectedPos = position;
				//highlight the selected item
				mAdapter.setSelectedPosition(position);
				
				loadDialog();
				
				return false;
			}
		});
		
		lv.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				
				//highlight the selected item
				mAdapter.setSelectedPosition(position);
			}
		});
	}
	
	private void getTypesList(){
		ArrayList<Object> workingList;
		
		try{
			mTypes = new ArrayList<ExpenseType>();
			mDBProvider.open();
			workingList = mDBProvider.selectAll(BudgetTable.EXPENSE_TYPE, getApplicationContext().getString(R.string.expense_type_name) + " asc", "type_of = ?", new String[] {Integer.toString(mTypeOf)});
			mDBProvider.close();
			
			for (Object obj : workingList){
				mTypes.add((ExpenseType)obj);
			}
			
			workingList = null;
			
			Thread.sleep(500);
			Log.i("ARRAY", ""+ mTypes.size());
		} catch (Exception e) {
			Log.e(TAG, e.getStackTrace().toString());
		}
		
		runOnUiThread(returnRes);
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		if (mProgressDialog != null){mProgressDialog.cancel();}
		
	}
	
	@Override
	public void onSaveInstanceState(Bundle instanceState) {
		//app is either being killed, paused or flipped
		super.onSaveInstanceState(instanceState);
		
		//save the globals we know that affect the display of the list
		instanceState.putInt("typeOf", mTypeOf);
		instanceState.putInt("selectedPos", mSelectedPos);
		
		 
		//TODO: what if the dialog is open, changes haven't been saved then?
		//		can i tell if it's opened? Probably
		
		instanceState.putParcelableArrayList("types", mTypes);
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		try {
			MenuInflater inflater = getMenuInflater();
			inflater.inflate(R.menu.types_edit_menu, menu);
			return true;
		} catch (Exception e) {
			Log.e(TAG, e.getStackTrace().toString());
			return false;
		}
	}
    
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		
		try {
			// Handle item selection
			switch (item.getItemId()) {
			case R.id.type_add:
				mSelectedPos = -1;
				loadDialog();
				return true;
			case R.id.type_edit:
				if (mSelectedPos != -1) {
					loadDialog();
				} else {
					Toast.makeText(getApplicationContext(), "No item is selected!", Toast.LENGTH_SHORT).show();
				}
				return true;
			case R.id.type_delete:
				if (mSelectedPos != -1) {
					ExpenseType type = mDBProvider.new ExpenseType();
					type._ID = mAdapter.getSelectedItemID();
					//TODO: do we need to confirm the delete?
					type.delete();
				} else {
					Toast.makeText(getApplicationContext(), "No item is selected!", Toast.LENGTH_SHORT).show();
				}
				setupListAdapter(true);
				return true;
			case R.id.type_switch:
				mSelectedPos = -1;
				mTypeOf = (mTypeOf == mDBProvider.EXPENSE_TYPES) ? mDBProvider.EXPENSE_GROUPS : mDBProvider.EXPENSE_TYPES;
				setupListAdapter(true);
				return true;
			case R.id.type_refresh:
				setupListAdapter(true);
				return true;
			case R.id.type_back:
				finish();
				return true;
			default:
				return super.onOptionsItemSelected(item);
			}
		} catch (Exception e) {
			Log.e(TAG, e.toString());
			return false;
		}
	}
	
	public void loadDialog()
	{
		//setup dialog
		mDialog = new Dialog(this, R.style.EditTypesDialog);
		mDialog.setContentView(R.layout.type_edit_dialog_view);	
		mDialog.setCancelable(true);
		mDialog.setOwnerActivity(this);
		
		if (mSelectedPos != -1) {
			((EditText)mDialog.findViewById(R.id.Edit_TypeName)).setText(mAdapter.getItem(mSelectedPos).NAME);
			((ColorSelectBar)mDialog.findViewById(R.id.Edit_TypeColor)).setColor(mAdapter.getItem(mSelectedPos).COLOR);
		}
		
		mDialog.show();
		
		((Button)mDialog.findViewById(R.id.Edit_TypeSave)).setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View view) {
				//here is where we validate and save
				saveTypeItem();
			}
		});
	}
	
	private void saveTypeItem() {
		
		mDBProvider.open();
		ExpenseType type = mDBProvider.new ExpenseType();
		
		type.NAME = ((EditText)mDialog.findViewById(R.id.Edit_TypeName)).getText().toString();
		type.COLOR = ((ColorSelectBar)mDialog.findViewById(R.id.Edit_TypeColor)).getColor();
		type.TYPE_OF = mTypeOf;
		
		if (mSelectedPos == -1) {
			type.insert();
		} else {
			type._ID = mAdapter.getSelectedItemID();
			type.update();
		}
		
		mDBProvider.close();
		
		mDialog.dismiss();
		
		((EditText)mDialog.findViewById(R.id.Edit_TypeName)).setText("");
		((ColorSelectBar)mDialog.findViewById(R.id.Edit_TypeColor)).setColor();
		
		setupListAdapter(true);
	}
	
	public class typeListAdapter extends ArrayAdapter<ExpenseType> {
		private final ArrayList<ExpenseType> mItems;
		
		public typeListAdapter(Context context, int textViewResourceId, ArrayList<ExpenseType> items) {
			super(context, textViewResourceId, items);
			this.mItems = items;
		}
		
		public void setSelectedPosition(int pos){
			mSelectedPos = pos;
			
			// inform the view of this change
			notifyDataSetChanged();
		}
		
		public int getSelectedPosition(){
			return mSelectedPos;
		}
		
		public long getSelectedItemID() {
			ExpenseType expenseTypes = mItems.get(mSelectedPos);
			
			return expenseTypes._ID;
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View v = convertView;
			if (v == null) {
				LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				v = vi.inflate(R.layout.types_edit_list_item, null);
			}
			
			LinearLayout ll = (LinearLayout)v.findViewById(R.id.type_list_item);
			//Possible EXIT
			if (ll == null) { return v; }
			TextView name = ((TextView)v.findViewById(R.id.type_name));
			//Possible EXIT
			if (name == null) { return v; }
			
			if(mSelectedPos == position){
				name.setTextColor(Color.parseColor(getApplicationContext().getString(R.color.gold)));
				ll.setBackgroundResource(R.drawable.list_item_selected);
			} else {
				name.setTextColor(Color.parseColor(getApplicationContext().getString(R.color.light_gray)));
				ll.setBackgroundResource(R.drawable.list_item_unselected);
			}
			
			ExpenseType expenseTypes = mItems.get(position);
			
			if (expenseTypes != null) {
				TextView tv = (TextView) v.findViewById(R.id.type_name);
				TextView id = (TextView) v.findViewById(R.id.type_id);
				
 				if (tv != null) { tv.setText(expenseTypes.NAME); }
				if (id != null){ id.setText(Long.toString(expenseTypes._ID)); }
			}
			
			return v;
		}
	}
}